/* eslint-disable prettier/prettier */
import React, { useState, useRef, useEffect, useCallback } from 'react';
import { View, Text, TextInput, FlatList, StyleSheet, Keyboard, Image, TouchableWithoutFeedback, TouchableOpacity, PermissionsAndroid } from 'react-native';
import 'dayjs/locale/zh-cn';
import { pTx } from "../../utils/dimensions"
import { debounce } from "../../utils/useDebounce"
import { getLaunchImageLibrary } from "../../utils/launchImageLibrary"
import { useRealm, useQuery } from '@realm/react'
import { schemaName } from "../../realm"
import { useNavigation } from '@react-navigation/native';
import Realm from "realm"
import VoicePressable from "../../components/voicePressable"
import httpApi from "../../api"
import ImageEquallyEnlarge from "../../components/imageEquallyEnlarge"
import ImageEquallyEnlargeVideo from "../../components/imageEquallyEnlargeVideo"
import PersonalBusinessCard from "../../components/personalBusinessCard"
import FriendTransferInApp from "../../components/friendTransferInApp"
import FriendGrabRedPacket from "../../components/friendGrabRedPacket"
import FriendRedPacketInApp from "../../components/friendRedPacketInApp"
import { showModal } from "../../components/rootSiblings/showModal"
import NavigateModalSelect from "../../components/rootSiblings/navigateModalSelect"
import PlayVoice from "../../components/playVoice"
import EmojiSelectorList from "../../components/emojiSelectorList"
import ImageView from "react-native-image-viewing";
import AudioRecorderPlayer from 'react-native-audio-recorder-player';
const audioRecorderPlayer = new AudioRecorderPlayer();

/**
 *  100 条历史消息，先给 10 条最新的，再给 10 条
 *  也就是先给 91 - 100, 再给 81 - 90, 依次类推
 */
const getData = (page, size, msgLis) => {
    return new Promise(resolve => {
        const allData = msgLis
        const newRes = allData.slice(page * size, page * size + size)
        resolve(newRes);
    });
};

const isAuthor = (id) => !(id > 0)
const RenderItemInfo = (props) => {
    const [visible, setVisible] = useState(false)
    const [images, setImages] = useState([])
    const { item, index, updateParentState, playVoiceRefs } = props
    const M = item.M?.split(' ')
    switch (item.MT) {
        case 0:
            return <Text style={styles.messageText} selectable>{item.M}</Text>
        case 2:
            return <TouchableWithoutFeedback onPress={() => {
                setVisible(true)
                setImages([
                    {
                        uri: (M[1].slice(0, 4) != "file" ? httpApi.inline : "") + M[1]
                    }
                ])
            }}>
                <View>
                    <ImageEquallyEnlarge
                        style={styles.imageEqually}
                        source={{ uri: (M[1].slice(0, 4) != "file" ? httpApi.inline : "") + M[1] }}
                        width={pTx(100)}
                    />
                    <ImageView
                        images={images}
                        imageIndex={0}
                        visible={visible}
                        onRequestClose={() => setVisible(false)}
                    />
                </View>
            </TouchableWithoutFeedback>
        case 3:
            return <ImageEquallyEnlargeVideo {...props} style={styles.imageEqually}
                source={require('../../assets/image/icon36.png')}
                width={pTx(120)}></ImageEquallyEnlargeVideo>
        case 5:
            return <TouchableWithoutFeedback onPress={() => props.onStopPlayDebounce(item, item._id)}>
                <View>
                    <PlayVoice
                        ref={(ref) => {
                            props.playVoiceRefs[item._id] = ref;
                        }}
                        {...props}
                        item={item}
                    />
                </View>
            </TouchableWithoutFeedback>
        case 6:
            return <PersonalBusinessCard {...props} item={item} />
        case 7:
            return <FriendTransferInApp {...props} item={item} />
        case 9:
            return <FriendGrabRedPacket {...props} item={item} />
        case 14:
            return <View style={styles.RedPacketBox}>
                {
                    item.S == -1 ?
                        <Text style={styles.RedPacket}>你领取了{props.params?.R}的<Text style={[{ color: "#F35E4D" }]}>红包</Text></Text>
                        :
                        <Text style={styles.RedPacket}>{props.params?.R}领取了你的<Text style={[{ color: "#F35E4D" }]}>红包</Text></Text>
                }
            </View>

    }
}
const DetailScreen = ({ detailScreenRefs, params }) => {
    const realm = useRealm();
    const userInfo = useQuery(schemaName.UserInfo, userInfo => {
        return userInfo.filtered('Current = true');
    })[0];
    const friendMsgLis = useQuery(schemaName.FriendMsgLis, friendMsg => {
        return friendMsg.filtered(`F == ${params.F} and UserId == ${userInfo.Id} and MT < 40`).sorted('T', true)
    })
    const navigation = useNavigation();
    const playVoiceRefs = useRef(null)
    const [playVoiceRefsIndex, setPlayVoiceRefsIndex] = useState("")
    const curPageRef = useRef(1);
    const SIZE = 20;
    const [msgLis, setMsgLis] = useState(JSON.parse(JSON.stringify(friendMsgLis)));
    const [data, setData] = useState(friendMsgLis.slice(0, SIZE));


    const handleOnEndReached = () => {
        getData(curPageRef.current, SIZE, msgLis).then(res => {
            setData([...data, ...res]);
        });
        curPageRef.current += 1;
    };

    const sendText = (msg) => {
        setData([msg, ...data])
    }

    const onMsgChange = (msg, changes) => {
        changes.insertions.forEach((index) => {
            const msgs = msg[index]
            realm.write(() => {
                msgs.Unread = 0
            });
            if (msgs.SendState == 2) {
                setList(prev => prev.map((element, idx) => {
                    element.SendState = msgs.SendState
                    return element
                }))
            } else {
                if (msgs.S == -1 && msgs.MT == 0) return
                setData([msgs, ...data])
            }
        });
    }

    useEffect(() => {
        realm.write(() => {
            const UnreadList = friendMsgLis.filtered(`Unread == 1`)
            for (const Msg of UnreadList) {
                Msg.Unread = 0
            }
        })
        friendMsgLis.addListener(onMsgChange);
        return () => {
            friendMsgLis.removeListener(onMsgChange);
        };
    }, [data]);

    const onStopPlayDebounce = debounce(async ([item, index]) => {
        audioRecorderPlayer.stopPlayer();
        audioRecorderPlayer.removePlayBackListener();
        playVoiceRefs[playVoiceRefsIndex]?.onStopPlay()
        if (!item) return setPlayVoiceRefsIndex(null)
        const [time, uri] = item?.M?.split(' ')
        if (playVoiceRefsIndex != index) {
            setPlayVoiceRefsIndex(index)
            await audioRecorderPlayer.startPlayer(httpApi.inline + uri);
            playVoiceRefs[index]?.onStartPlay()
        } else {
            setPlayVoiceRefsIndex(null)
        }
    }, 100, false)

    detailScreenRefs.current = {
        onStopPlayDebounce,
        sendText
    }


    const renderItem = ({ item, index }) => {
        return (item.F && <View>
            <View style={[styles.renderUserItem, isAuthor(item.S) && styles.renderUserItemRowReverse]}>
                {([14].indexOf(item.MT) === -1) && <View style={styles.renderAvatar}>
                    <TouchableWithoutFeedback onPress={() => {
                        var UserInfo
                        if (!isAuthor(item.S)) {
                            UserInfo = {
                                Id: params.F,
                                NickName: params.R,
                                ProfilePhoto: params.P,
                                Ms: params
                            }
                        } else {
                            UserInfo = userInfo
                        }
                        navigation.navigate('friendInfo', UserInfo)
                    }}>
                        <Image style={[styles.avatar]} source={{ uri: httpApi.inline + ((isAuthor(item.S) ? userInfo.ProfilePhoto : params.P) || httpApi.defaultAvatar) }}></Image>
                    </TouchableWithoutFeedback>
                </View>
                }
                <RenderItemInfo playVoiceRefs={playVoiceRefs} onStopPlayDebounce={onStopPlayDebounce} params={params} item={item} />
            </View>
            {item.SendState == 3 && <Text style={styles.youNotFriendText}>你还不是他（她）朋友。请先发送朋友验证请求，对方验证通过后，才能聊天</Text>}
        </View>
        )
    }
    const keyboardDismiss = () => {
        Keyboard.dismiss();
    }
    return (
        <>
            <FlatList
                style={{ flex: 1 }}
                onEndReached={handleOnEndReached}
                renderItem={renderItem}
                contentContainerStyle={{
                    flexGrow: 1,
                    justifyContent: 'flex-end',
                }}
                inverted
                data={data}
                onScroll={keyboardDismiss}
                initialNumToRender={20}
                keyExtractor={(item, index) => index}
            />

        </>
    );
};

const DetailScreenhildComponent = React.memo(DetailScreen);

const FriendMsg = (props) => {
    const detailScreenRefs = useRef()
    const sendRedPacketInRefs = useRef(null)
    const textInputRef = useRef(null);

    const [isTextVoice, setIsTextVoice] = useState(false)
    const [moreFeaturesOpen, setMoreFeaturesOpen] = useState(false)
    const [openEmoji, setOpenEmoji] = useState(false)

    const [text, setText] = useState("")
    const params = props.route.params

    const realm = useRealm();
    const userInfo = useQuery(schemaName.UserInfo, userInfo => {
        return userInfo.filtered('Current = true');
    })[0];
    const friend = useQuery(schemaName.FriendList, friend => {
        return friend.filtered(`UserId == ${userInfo.Id} and F == ${params.F}`);
    })[0];
    useEffect(() => {
        httpApi.getFriendInfo({ id: params.F }).then(res => {
            if (res.code == 20) {
                const UserFriend = res.data.UserFriend
                if (UserFriend.P != friend.P || UserFriend.R != friend.R) {
                    realm.write(() => {
                        realm.create(schemaName.FriendList, UserFriend, true)
                    })
                }

            }
        })
    }, [])

    const onTextSend = async () => {
        const Text = text
        setText("")
        setTimeout(async () => {
            var timestamp = Date.parse(new Date()) / 1000
            const realmItem = {
                F: params.F,
                M: Text,
                MT: 0,
                S: -1,
                T: timestamp,
                _id: new Realm.BSON.UUID(),
                Unread: 0,
                UserId: userInfo.Id
            }
            detailScreenRefs.current.sendText(realmItem)
            realm.write(() => {
                realm.create(schemaName.FriendMsgLis, realmItem, true);
            })
            const res = await httpApi.sendFriendText({ message: realmItem.M, id: params.F })
            if (res.code != 20) {
                realm.write(() => {
                    realm.create(schemaName.FriendMsgLis, { ...realmItem, SendState: 2 }, true);
                })
            }
        })
    }
    const sendFriendFile = async () => {
        try {
            let File = await getLaunchImageLibrary()
            File = File.uri ? File : File[0]
            const msgType = File.type == 'image/jpeg' ? 2 : 3
            var timestamp = Date.parse(new Date()) / 1000
            let MsgLisLength = new Realm.BSON.UUID()
            const realmItem = {
                F: params.F,
                M: File.fileSize + " " + File.uri + " " + File.fileName,
                MT: msgType,
                T: timestamp,
                S: -1,
                _id: MsgLisLength,
                Unread: 0,
                UserId: userInfo.Id
            }
            realm.write(() => {
                realm.create(schemaName.FriendMsgLis, realmItem, true);
            })
            const image = await httpApi.uploadMinio(File)
            const res = await httpApi.sendFriendFile({
                id: params.F,
                msgType,
                srcFileName: File.fileName,
                dstFileName: image.data.FileNames[0],
                fileSize: File.fileSize
            })
            if (res.code != 20) {
                realm.write(() => {
                    realm.create(schemaName.FriendMsgLis, { ...realmItem, SendState: 2 }, true);
                })
            }
        } catch (error) {
            console.log(error)
        }
    }

    const sendFriendContactCard = async () => {
        try {
            const res = await httpApi.sendFriendContactCard({
                id: params.F,
                friendId: userInfo.Id,
            })
            var timestamp = Date.parse(new Date()) / 1000
            const realmItem = {
                F: params.F,
                M: res.data.FriendInfo,
                MT: 6,
                S: -1,
                T: timestamp,
                _id: new Realm.BSON.UUID(),
                Unread: 0,
                UserId: userInfo.Id
            }
            realm.write(() => {
                realm.create(schemaName.FriendMsgLis, realmItem, true);
            })
        } catch (error) {
            console.log(error)
        }
    }

    useEffect(() => {
        const showSubscription = Keyboard.addListener('keyboardDidShow', () => {
            setIsTextVoice(false)
            setMoreFeaturesOpen(false)
            setOpenEmoji(false)
        });
        const hideSubscription = Keyboard.addListener('keyboardDidHide', () => {
        });

        return () => {
            showSubscription.remove();
            hideSubscription.remove();
        };
    }, []);

    useEffect(() => {
        props.navigation.setOptions({
            headerTitle: ({ options }) => (
                <Text style={styles.headerTitle} ellipsizeMode={'tail'} numberOfLines={1}>{props.route.params.R}</Text>
            )
        });

        if (Platform.OS === 'android') {
            try {
                PermissionsAndroid.requestMultiple([
                    PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
                    PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
                    PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
                ]).then(grants => {
                    if (
                        grants['android.permission.WRITE_EXTERNAL_STORAGE'] ===
                        PermissionsAndroid.RESULTS.GRANTED &&
                        grants['android.permission.READ_EXTERNAL_STORAGE'] ===
                        PermissionsAndroid.RESULTS.GRANTED &&
                        grants['android.permission.RECORD_AUDIO'] ===
                        PermissionsAndroid.RESULTS.GRANTED
                    ) {
                    } else {
                        return;
                    }
                })

            } catch (err) {
                return;
            }
        }
    }, [])

    return (
        <View style={styles.mainContent}>
            <DetailScreenhildComponent detailScreenRefs={detailScreenRefs} params={params} />
            <View style={styles.footRender}>
                <View style={styles.footRenderRow}>
                    <TouchableOpacity onPress={() => {
                        setIsTextVoice(isTextVoice ? false : true)
                        setMoreFeaturesOpen(false)
                        setOpenEmoji(false)
                        setTimeout(() => {
                            isTextVoice && textInputRef?.current && textInputRef.current.focus()
                        })
                    }}>
                        <View style={[{ marginLeft: pTx(8) }]}>
                            <Image style={[styles.footImage]} source={isTextVoice ? require('../../assets/image/icon35.png') : require('../../assets/image/icon13.png')}></Image>
                        </View>
                    </TouchableOpacity>
                    <View style={styles.renderComposer}>
                        {!isTextVoice ? <TextInput ref={textInputRef} value={text} onChangeText={(e) => setText(e)} style={[styles.composer]} multiline maxLength={200}
                        />
                            :
                            <VoicePressable
                                {...props}
                                onStopPlayDebounce={() => detailScreenRefs.current.onStopPlayDebounce()} />
                        }
                    </View>
                    <View style={styles.rightRenderSend}>
                        <TouchableOpacity onPress={() => {
                            Keyboard.dismiss();
                            setTimeout(() => {
                                setOpenEmoji(openEmoji ? false : true)
                                setMoreFeaturesOpen(false)
                                setIsTextVoice(false)
                            }, 100)
                        }}>
                            <Image style={[styles.footImage]} source={require('../../assets/image/icon12.png')}></Image>
                        </TouchableOpacity>
                        {text && !isTextVoice ? <Text style={[styles.sendBtn]} onPress={() => onTextSend()}>
                            发送
                        </Text>
                            :
                            <TouchableOpacity onPress={() => {
                                Keyboard.dismiss();
                                setTimeout(() => {
                                    setOpenEmoji(false)
                                    setMoreFeaturesOpen(moreFeaturesOpen ? false : true)
                                    setIsTextVoice(true)
                                }, 100)
                            }}>
                                <Image style={[styles.footImage]} source={require('../../assets/image/icon14.png')}></Image>
                            </TouchableOpacity>
                        }
                    </View>
                </View>
                <View>
                    {moreFeaturesOpen && <View style={[styles.moreFeatures]}>
                        <TouchableWithoutFeedback onPress={() => sendFriendFile()}>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon26.png')}></Image>
                                <Text style={styles.featuresTexy}>图片</Text>
                            </View>
                        </TouchableWithoutFeedback>
                        <TouchableWithoutFeedback>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon27.png')}></Image>
                                <Text style={styles.featuresTexy}>文件</Text>
                            </View>
                        </TouchableWithoutFeedback>
                        <TouchableWithoutFeedback>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon28.png')}></Image>
                                <Text style={styles.featuresTexy}>语音聊天</Text>
                            </View>
                        </TouchableWithoutFeedback>
                        <TouchableWithoutFeedback>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon25.png')}></Image>
                                <Text style={styles.featuresTexy}>视频聊天</Text>
                            </View>
                        </TouchableWithoutFeedback>
                        <TouchableWithoutFeedback onPress={() => sendRedPacketInRefs.current.setOpen(true)}>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon23.png')}></Image>
                                <Text style={styles.featuresTexy}>红包</Text>
                            </View>
                        </TouchableWithoutFeedback>
                        <TouchableWithoutFeedback onPress={() => showModal(<NavigateModalSelect operation={
                            [
                                { text: '站内转帐', onPress: () => props.navigation.navigate('friendTransferInApp', props.route.params) },
                                // { text: '区块链转帐', onPress: () => console.log('FriendTransferInApp') },
                            ]
                        } />)}>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon29.png')}></Image>
                                <Text style={styles.featuresTexy}>转帐</Text>
                            </View>
                        </TouchableWithoutFeedback>
                        <TouchableWithoutFeedback onPress={() => sendFriendContactCard()}>
                            <View style={[styles.featuresCell]}>
                                <Image style={styles.featuresImage} source={require('../../assets/image/icon24.png')}></Image>
                                <Text style={styles.featuresTexy}>名片</Text>
                            </View>
                        </TouchableWithoutFeedback>
                    </View>
                    }
                    {openEmoji && <EmojiSelectorList state={(el) => setText(text + el)} />}
                </View>
            </View >
            <FriendRedPacketInApp {...props} ref={sendRedPacketInRefs} />

        </View >
    )
}

export default FriendMsg

const styles = StyleSheet.create({
    headerTitle: {
        maxWidth: pTx(250),
        fontSize: pTx(18),
        color: "#000"
    },
    message: {
        fontSize: 30,
        flex: 1,
        margin: 10,
        backgroundColor: '#FFF',
    },
    mainContent: {
        flex: 1,
        backgroundColor: 'rgba(237, 237, 237, 1)',
    },
    footRender: {
        paddingVertical: pTx(9),

        backgroundColor: "rgba(247, 247, 247, 1)",
    },
    footRenderRow: {
        flexDirection: "row",
        alignItems: "flex-end",
    },
    renderComposer: {
        flex: 1,
        flexDirection: "row",
        alignItems: "center",
    },
    composer: {
        flex: 1,
        fontSize: pTx(16),
        borderRadius: pTx(4),
        minHeight: pTx(40),
        paddingVertical: pTx(2),
        paddingHorizontal: pTx(10),
        backgroundColor: "#ffffff",
    },
    renderUserItem: {
        paddingVertical: pTx(10),
        flexDirection: "row",
        alignItems: "flex-start"
    },
    renderUserItemRowReverse: {
        flexDirection: "row-reverse",
    },
    renderAvatar: {
        paddingHorizontal: pTx(15),
    },
    avatar: {
        height: pTx(40),
        width: pTx(40),
        borderRadius: pTx(8),
    },
    messageText: {
        paddingVertical: pTx(10),
        fontSize: pTx(15),
        color: "#333333",
        paddingHorizontal: pTx(10),
        backgroundColor: "#ffffff",
        borderRadius: pTx(8),
        maxWidth: pTx(260),
    },
    youNotFriendText: {
        paddingHorizontal: pTx(20),
        textAlign: "center",
        opacity: 0.6,
        fontSize: pTx(12),
    },


    sendBtn: {
        paddingHorizontal: pTx(12),
        marginBottom: pTx(5),
        height: pTx(30),
        fontSize: pTx(16),
        color: "#fff",
        backgroundColor: "rgba(6, 193, 97, 1)",
        borderRadius: pTx(4),
        textAlignVertical: "center"
    },
    containerStyle: {
        backgroundColor: "#EDEDED",
        paddingVertical: pTx(8),
    },
    textInputStyle: {
        fontSize: pTx(16),
        borderRadius: pTx(4),
        minHeight: 0,
        paddingVertical: pTx(5),
        paddingHorizontal: pTx(10),
        marginVertical: 0,
        backgroundColor: "#ffffff",
    },
    rightRenderSend: {
        marginHorizontal: pTx(10),
        flexDirection: "row",
        alignItems: "center"
    },
    footImage: {
        marginRight: pTx(8),
        marginBottom: pTx(4),
        width: pTx(30),
        height: pTx(30),
    },


    moreFeatures: {
        flexDirection: "row",
        flexWrap: "wrap",
        columnGap: pTx(32),
        paddingHorizontal: pTx(27),
        paddingTop: pTx(13),
    },
    featuresCell: {
        marginVertical: pTx(8),
        alignItems: "center",
    },
    featuresImage: {
        height: pTx(53),
        width: pTx(53),
    },
    featuresTexy: {
        marginTop: pTx(5),
        textAlign: "center",
        fontSize: pTx(12),
        color: "#727272"
    },

    imageEqually: {
        marginTop: pTx(5),
    },
    backgroundVideo: {
        width: pTx(150),
        height: pTx(100),
        backgroundColor: "#000"
    },
    RedPacketBox: {
        flex: 1,
        flexDirection: "row",
        justifyContent: "center"
    },
    RedPacket: {
        textAlign: "center",
        fontSize: pTx(12),
    }
});

